(function ($) { // Note: Chosen's browser detection has been patched in chosen.jquery.min.js // to always return true for all browsers (except IE which needs document mode check). // This enables Chosen on all Android devices, iPhones, and other mobile devices. $(document).ready(function () { // Function to enhance Chosen dropdowns for accessibility function enhanceChosenAccessibility() { // First, ensure all select elements have explicit labels $('select.filter-dropdown').each(function() { const select = $(this); const selectId = select.attr('id'); const labelText = select.attr('data-placeholder') || 'Select an option'; // Check if there's already a label for this select const existingLabel = $('label[for="' + selectId + '"]'); if (existingLabel.length === 0) { // Create a visible label for SiteImprove compliance select.before(''); } }); // Fix empty containers that SiteImprove flags $('div.chosen-drop, div.chosen-container, span.chosen-single span, ul.chosen-results, ul.chosen-choices').each(function() { const container = $(this); // Check if the container is empty if (container.children().length === 0 && !container.text().trim()) { // Add a hidden span with text for screen readers const containerType = container.prop('tagName').toLowerCase(); const containerClass = container.attr('class') || ''; let placeholderText = 'Select an option'; // Determine appropriate placeholder text based on container type if (containerClass.includes('chosen-single') && containerClass.includes('chosen-default')) { // For default single select, use the placeholder from the original select const originalId = container.closest('.chosen-container').attr('id').replace('_chosen', ''); const originalSelect = $('#' + originalId); placeholderText = originalSelect.attr('data-placeholder') || 'Select an option'; } else if (containerClass.includes('chosen-results')) { placeholderText = 'Options will appear here'; } else if (containerClass.includes('chosen-choices')) { placeholderText = 'Selected options will appear here'; } // Add appropriate content based on container type if (containerType === 'ul') { container.html('
  • ' + placeholderText + '
  • '); } else { container.html('' + placeholderText + ''); } } }); // Add ARIA attributes to all chosen-results lists $(".chosen-results").each(function() { $(this).attr({ 'role': 'listbox', 'aria-live': 'polite' }); // Add a placeholder item if the list is empty if ($(this).children().length === 0 || ($(this).children().length === 1 && $(this).children().first().hasClass('accessibility-placeholder'))) { $(this).html('
  • Items will be displayed upon interaction.
  • '); } }); // Fix accessibility for each Chosen container $(".chosen-container").each(function() { const container = $(this); // Get the original select element's ID by removing '_chosen' from the container ID const originalId = container.attr('id').replace('_chosen', ''); const selectElement = $('#' + originalId); // Skip if we can't find the original select if (selectElement.length === 0) return; // Find the label for this select const existingLabel = $('label[for="' + originalId + '"]'); let labelText = selectElement.attr('data-placeholder') || 'Select an option'; // If there's an existing label, use its text if (existingLabel.length > 0) { labelText = existingLabel.text(); } // Generate a unique ID for accessibility elements const uniqueId = originalId + '-accessible'; // Ensure the original select has an explicit label with an ID if (existingLabel.length > 0) { existingLabel.attr('id', originalId + '-label'); } else { // Create a label if none exists container.before(''); } // Add proper ARIA attributes to the container container.attr({ 'role': 'combobox', 'aria-expanded': 'false', 'aria-haspopup': 'true', 'aria-owns': uniqueId + '-results', 'aria-labelledby': originalId + '-label' }); // Add ID to the results container const resultsContainer = container.find('.chosen-results'); resultsContainer.attr('id', uniqueId + '-results'); // Fix the search input field const searchField = container.find('.chosen-search-input'); if (searchField.length) { searchField.attr({ 'id': uniqueId + '-search', 'aria-label': 'Search ' + labelText, 'aria-controls': uniqueId + '-results' }); } // Handle single select Chosen containers if (container.hasClass('chosen-container-single')) { const chosenSingle = container.find('.chosen-single'); chosenSingle.attr({ 'id': uniqueId, 'role': 'button', 'aria-labelledby': originalId + '-label' }); // Add a label specifically for the a.chosen-single element that SiteImprove sees as a form control if ($('label[for="' + uniqueId + '"]').length === 0) { chosenSingle.before(''); } } // Handle multi select Chosen containers else if (container.hasClass('chosen-container-multi')) { const chosenChoices = container.find('.chosen-choices'); chosenChoices.attr({ 'id': uniqueId, 'role': 'listbox', 'aria-labelledby': originalId + '-label' }); // Add a label specifically for the ul.chosen-choices element if ($('label[for="' + uniqueId + '"]').length === 0) { chosenChoices.before(''); } // Also label the input field inside chosen-choices that SiteImprove might flag const inputField = chosenChoices.find('input'); if (inputField.length) { const inputId = uniqueId + '-input'; inputField.attr('id', inputId); if ($('label[for="' + inputId + '"]').length === 0) { inputField.before(''); } } } // Set up MutationObserver to watch for changes in the results list if (resultsContainer.length && typeof MutationObserver !== 'undefined') { const observer = new MutationObserver(function(mutations) { // When results are populated, ensure there's always at least one item if (resultsContainer.children().length === 0) { resultsContainer.html('
  • Items will be displayed upon interaction.
  • '); } else if (resultsContainer.children().length === 1 && resultsContainer.children().first().hasClass('no-results')) { // If "no results" is the only item, keep it but add proper role resultsContainer.children().first().attr('role', 'option'); } else { // Remove placeholder if real results are present resultsContainer.find('.accessibility-placeholder').remove(); } }); // Start observing the results container observer.observe(resultsContainer[0], { childList: true, subtree: true }); } }); } // Initial enhancement with a delay to ensure Chosen has initialized setTimeout(enhanceChosenAccessibility, 500); // Re-apply enhancements when Chosen is updated or when dropdowns are shown $(document).on('chosen:showing_dropdown chosen:ready chosen:updated', function() { enhanceChosenAccessibility(); }); // Also apply when window is fully loaded (backup) $(window).on('load', enhanceChosenAccessibility); // Apply aria-labels to generic Learn More and Apply Now links // ------------------------------------------------------------------ // Select all links with text "Learn More" or "Apply Now" $('a').filter(function () { var text = $(this).text().trim().toLowerCase(); return text === 'learn more' || text === 'apply now'; }).each(function () { var link = $(this); // Current link element var href = link.attr('href'); // Get the href attribute // Check if href exists to avoid errors if (href) { // Extract the last part of the URL after the last slash var slug = href.split('/').filter(function (part) { return part.length > 0; // Remove empty parts caused by trailing slashes }).pop(); // Determine the type of link var linkText = link.text().trim(); var ariaLabel; // Customize the aria-label text based on the link text if (linkText.toLowerCase() === 'learn more') { ariaLabel = 'Learn more about ' + slug.replace(/-/g, ' '); } else if (linkText.toLowerCase() === 'apply now') { ariaLabel = 'Apply now to ' + slug.replace(/-/g, ' '); } // Set the aria-label attribute link.attr('aria-label', ariaLabel); } }); }); })(jQuery);